package com.pb.b2b.util;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.el.ELResolver;
import javax.faces.application.FacesMessage;
import javax.faces.application.FacesMessage.Severity;
import javax.faces.bean.ManagedBean;
import javax.faces.context.FacesContext;
import javax.faces.context.Flash;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;

import com.pb.b2b.common.bean.UserSessionBean;

public class FacesUtils {

	protected static final String RESOURCE_BUNDLE = "resources.messages";

	public static FacesContext getFacesContext() {
		return FacesContext.getCurrentInstance();
	}

	public static String getResourceBundleString(String moduleBundleName, String key, Object[] parameters) {
		return getResourceBundleString(moduleBundleName, key, parameters, null);
	}

	public static String getResourceBundleString(String moduleBundleName, String key, Object[] parameters, Locale locale) {
		String value = null;

		Locale localLocale = null;
		if (locale == null)
			localLocale = getLocale();
		else
			localLocale = locale;
		if (locale == null) {
			if (getLocale() != null)
				localLocale = getLocale();
		}
		ResourceBundle bundle = ResourceBundle.getBundle(moduleBundleName, localLocale);
		if (bundle == null)
			return key;
		try {
			value = bundle.getString(key);
		} catch (MissingResourceException e) {
			value = key;
		}
		if (value == null)
			return StringUtils.EMPTY;
		if (parameters != null)
			value = MessageFormat.format(value, parameters);
		return value;
	}

	public static String getResourceBundleString(ResourceBundle bundle, String key, Object[] parameters) {
		if (bundle == null)
			return key;
		String value = null;
		try {
			value = bundle.getString(key);
		} catch (MissingResourceException e) {
			value = key;
		}
		if (value == null)
			return StringUtils.EMPTY;
		if (parameters != null)
			value = MessageFormat.format(value, parameters);
		return value;
	}

	public static void addMessage(Severity severity, String messageKey) {
		String message = getResourceBundleString(RESOURCE_BUNDLE, messageKey, null);
		getFacesContext().addMessage(null, new FacesMessage(severity, message, message));
	}

	public static void addMessage(Severity severity, String messageKey, Object[] parameters) {
		String message = getResourceBundleString(RESOURCE_BUNDLE, messageKey, parameters);
		getFacesContext().addMessage(null, new FacesMessage(severity, message, message));
	}

	public static UserSessionBean getUserSession() {
		UserSessionBean userSession = (UserSessionBean) getManagedSessionBean("UserSessionBean");
		return userSession;
	}

	public static Object getManagedSessionBean(String beanName) {
		ELResolver resolver = getFacesContext().getApplication().getELResolver();
		return resolver.getValue(getFacesContext().getELContext(), null, beanName);
	}

	public static void setManagedBean(String beanName, Object value) {
		ELResolver resolver = getFacesContext().getApplication().getELResolver();
		resolver.setValue(getFacesContext().getELContext(), null, beanName, value);
	}

	/* Save Bean */

	public static void setParameter(String key, Object value) {
		Map<String, Object> map = getFacesContext().getExternalContext().getSessionMap();
		map.put(key, value);
	}

	public static Object getParameter(String key) {
		Map<String, Object> map = getFacesContext().getExternalContext().getSessionMap();
		if (map.containsKey(key)) {
			Object value = map.get(key);
			return value;
		}
		return null;
	}

	public static Locale getLocale() {
		return getFacesContext().getViewRoot().getLocale();
	}

	public static String getViewId() {
		if (FacesContext.getCurrentInstance() != null && FacesContext.getCurrentInstance().getViewRoot() != null)
			return FacesContext.getCurrentInstance().getViewRoot().getViewId();
		else
			return StringUtils.EMPTY;
	}

	public static Flash getFlash() {
		return getFacesContext().getExternalContext().getFlash();
	}

	public static Object flashGet(String parameter) {
		return getFlash().get(parameter);
	}

	public static void flashPutNow(String parameter, Object value) {
		getFlash().putNow(parameter, value);
	}

	public static void flashPut(String parameter, Object value) {
		getFlash().put(parameter, value);
	}

	public static void flashRemove(String parameter) {
		getFlash().remove(parameter);
	}

	public static boolean putFlashBeanToThis(Object toThis) {
		ManagedBean managedBean = toThis.getClass().getAnnotation(ManagedBean.class);
		String beanName = managedBean.name();
		Object flashObject = getFlash().get(beanName);
		if (flashObject != null) {
			try {
				BeanUtils.copyProperties(toThis, flashObject);
				return true;
			} catch (BeansException e) {
				e.printStackTrace();
			}
			return false;
		}
		return false;
	}

	public static void putThisToFlashBean(Object toThis) {
		ManagedBean managedBean = toThis.getClass().getAnnotation(ManagedBean.class);
		String beanName = managedBean.name();
		getFlash().put(beanName, toThis);
	}

	public static Object getViewMap(String beanName) {
		Object object = FacesContext.getCurrentInstance().getViewRoot().getViewMap().get(beanName);
		return object;
	}

	public static void setViewMap(String beanName, Object value) {
		FacesContext.getCurrentInstance().getViewRoot().getViewMap().put(beanName, value);
	}

	/**
	 * control
	 */

	public static Map<String, Object> getSessionMap() {
		return FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
	}

	public static boolean sessionMapContains(String key) {
		return getSessionMap().containsKey(key);
	}

	public static void sessionMapPut(String key, Object value) {
		getSessionMap().put(key, value);
	}

	public static Object sessionMapGet(String key) {
		return getSessionMap().get(key);
	}

	public static void sessionMapRemove(String key) {
		getSessionMap().remove(key);
	}

	public static Object sessionMapGetAndRemove(String key) {
		Object value;
		value = sessionMapGet(key);
		sessionMapRemove(key);
		return value;
	}

}
